/*
 * Android Runner is a multiplayer GPS game fully written by Xurxo Mendez Perez
 * 
 * Copyright (C) 2009 Xurxo Mendez Perez
 *   
 * This file is part of Android Runner.
 * 
 * Android Runner is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Android Runner is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Android Runner.  If not, see <http://www.gnu.org/licenses/>.
 */

package es.sonxurxo.androidrunner.view.xml;

import java.util.List;

import org.jdom.Element;

import es.sonxurxo.androidrunner.model.persistence.item.entity.Item;
import es.sonxurxo.androidrunner.model.service.game.to.AnswerQuestionResponseTO;
import es.sonxurxo.androidrunner.model.service.game.to.GameTO;
import es.sonxurxo.androidrunner.model.service.game.to.GameTOCTO;
import es.sonxurxo.androidrunner.model.service.game.to.GenericGameResponseTO;
import es.sonxurxo.androidrunner.model.service.game.to.GetItemResponseTO;
import es.sonxurxo.androidrunner.model.service.game.to.InGamePlayerInfoTO;
import es.sonxurxo.androidrunner.model.service.game.to.ItemTO;
import es.sonxurxo.androidrunner.model.service.game.to.MessageTO;
import es.sonxurxo.androidrunner.model.service.game.to.ObserveGameResponseTO;
import es.sonxurxo.androidrunner.model.service.game.to.StartOrContinueGameResponseTO;
import es.sonxurxo.androidrunner.model.service.game.to.UpdateLocationResponseTO;
import es.sonxurxo.androidrunner.model.service.player.to.FinishedGameRankingTO;
import es.sonxurxo.androidrunner.model.service.player.to.LoginResultTO;
import es.sonxurxo.androidrunner.model.service.player.to.PlayerHistoryTO;
import es.sonxurxo.androidrunner.model.service.player.to.PublicPlayerProfileTO;
import es.sonxurxo.androidrunner.util.DateOperations;

/**
 * 
 * @author "Xurxo Mendez Perez"
 *
 */
public class TOToXMLConversor {

	public static final String OK_LOGOUT_ELEMENT_NAME = "logout";
	public static final String OK_PASSWORD_CHANGED_ELEMENT_NAME = "passwordChanged";
	public static final String OK_REGISTERED_ELEMENT_NAME = "registered";
	public static final String OK_UPDATED_ELEMENT_NAME = "updated";
	public static final String OK_MESSAGE_SENT_ELEMENT_NAME = "messageSent";
	public static final String OK_JOINED_ELEMENT_NAME = "joined";
	public static final String OK_ABANDON_GAME_ELEMENT_NAME = "abandoned";
	
	public static Element toXML(LoginResultTO loginResultTO) {
		Element playerElement = new Element("player");
		Element loginElement = new Element("login").setText(
				loginResultTO.getLogin());
		playerElement.addContent(loginElement);

		Element showPersonalInfoElement = new Element("showPersonalInfo").setText(
				String.valueOf(loginResultTO.isShowPersonalInfo()));
		playerElement.addContent(showPersonalInfoElement);
		Element emailElement = new Element("email").setText(loginResultTO.getEmail());
		playerElement.addContent(emailElement);
		Element phoneElement = new Element("phone").setText(loginResultTO.getPhone());
		playerElement.addContent(phoneElement);
		Element nameElement = new Element("name").setText(
				loginResultTO.getName());
		playerElement.addContent(nameElement);
		Element surnameElement = new Element("surname").setText(
				loginResultTO.getSurname());
		playerElement.addContent(surnameElement);
		Element countryElement = new Element("country").setText(
        		loginResultTO.getCountry());
		Element imageIdElement = new Element("imageId").setText(
				String.valueOf(loginResultTO.getImageId()));
		Element totalPointsElement = new Element("totalPoints").setText(
				String.valueOf(loginResultTO.getTotalPoints()));
		Element maxPointsElement = new Element("maxPoints").setText(
				String.valueOf(loginResultTO.getMaxPoints()));
		Element bestRankElement = new Element("bestRank").setText(
        		String.valueOf(loginResultTO.getBestRank()));
		
		if (loginResultTO.getGameId() != -1) {
			Element gameIdElement = new Element("gameId").setText(
	        		String.valueOf(loginResultTO.getGameId()));
			playerElement.addContent(gameIdElement);
		}
		
		playerElement.addContent(countryElement);
		playerElement.addContent(imageIdElement);
		playerElement.addContent(totalPointsElement);
		playerElement.addContent(maxPointsElement);
		playerElement.addContent(bestRankElement);
		return playerElement;
	}

	public static Element toXML(PublicPlayerProfileTO publicPlayerProfileTO) {
		Element playerElement = new Element("player");
		Element loginElement = new Element("login").setText(
        		publicPlayerProfileTO.getLogin());
		playerElement.addContent(loginElement);
		if (publicPlayerProfileTO.isShowPersonalInfo()) {
			Element emailElement = new Element("email").setText(publicPlayerProfileTO.getEmail());
			playerElement.addContent(emailElement);
			Element phoneElement = new Element("phone").setText(publicPlayerProfileTO.getPhone());
			playerElement.addContent(phoneElement);
			Element nameElement = new Element("name").setText(
	        		publicPlayerProfileTO.getName());
			playerElement.addContent(nameElement);
			Element surnameElement = new Element("surname").setText(
	        		publicPlayerProfileTO.getSurname());
			playerElement.addContent(surnameElement);
		}
		Element countryElement = new Element("country").setText(
        		publicPlayerProfileTO.getCountry());
		Element imageIdElement = new Element("imageId").setText(
				String.valueOf(publicPlayerProfileTO.getImageId()));
		Element totalPointsElement = new Element("totalPoints").setText(
				String.valueOf(publicPlayerProfileTO.getTotalPoints()));
		Element maxPointsElement = new Element("maxPoints").setText(
				String.valueOf(publicPlayerProfileTO.getMaxPoints()));
		Element bestRankElement = new Element("bestRank").setText(
        		String.valueOf(publicPlayerProfileTO.getBestRank()));
		
		playerElement.addContent(countryElement);
		playerElement.addContent(imageIdElement);
		playerElement.addContent(totalPointsElement);
		playerElement.addContent(maxPointsElement);
		playerElement.addContent(bestRankElement);
		return playerElement;
	}

	public static Element toXML(PlayerHistoryTO playerHistoryTO) {
		Element gamesElement = new Element("games");
		for (FinishedGameRankingTO fgrTO:playerHistoryTO.getGames()) {
			Element gameElement = new Element("game");
			Element gameIdElement = new Element("gameId").setText(
					String.valueOf(fgrTO.getGameId()));
			Element cityElement = new Element("city").setText(
					fgrTO.getCity());
			Element startDateElement = new Element("startDate").setText(
					DateOperations.formatDate(fgrTO.getStartDate()));
			gameElement.addContent(gameIdElement);
			gameElement.addContent(cityElement);
			gameElement.addContent(startDateElement);
			for (int i=0;i<fgrTO.getPoints().size();i++) {
				Element lineElement = new Element("rankingLine");
				Element loginElement = new Element("login").setText(
						fgrTO.getPlayerLogins().get(i));
				Element pointsElement = new Element("points").setText(
						String.valueOf(fgrTO.getPoints().get(i)));
				Element itemsCaughtedElement = new Element("numberOfItems").setText(
						String.valueOf(fgrTO.getItemsCaughted().get(i)));
				Element positionElement = new Element("position").setText(
						String.valueOf(fgrTO.getPositions().get(i)));
				lineElement.addContent(loginElement);
				lineElement.addContent(pointsElement);
				lineElement.addContent(itemsCaughtedElement);
				lineElement.addContent(positionElement);
				gameElement.addContent(lineElement);
			}
			gamesElement.addContent(gameElement);
		}
		return gamesElement;
	}
	
	public static Element toXML(Exception e, int code) {
		Element exceptionElement = new Element("exception");
		Element codeElement = new Element("code").setText(
        		String.valueOf(code));
		Element messageElement = new Element("message").setText(
        		e.getLocalizedMessage());
		exceptionElement.addContent(codeElement);
		exceptionElement.addContent(messageElement);

		return exceptionElement;
	}
	
	public static Element toXML(String elementName) {
		return new Element(elementName);
	}

	public static Element toXML(GameTOCTO gameTOCTO) {
		Element gameListElement = new Element("gameList");
		if (gameTOCTO.isHasMore()) {
			Element hasMoreElement = new Element("hasMore");
			gameListElement.addContent(hasMoreElement);
		}
		for (GameTO gameTO:gameTOCTO.getGameTOList()) {
			gameListElement.addContent(toXML(gameTO));
		}
		return gameListElement;
	}
	
	public static Element toXML(GameTO gameTO) {

		Element gameElement = new Element("game");
		Element gameIdElement = new Element("gameId").
			setText(String.valueOf(gameTO.getGameId()));
		Element startDateElement = new Element("startDate").
			setText(DateOperations.formatDate(gameTO.getStartDate()));
		Element finishDateElement = new Element("finishDate").
			setText(DateOperations.formatDate(gameTO.getFinishDate()));
		Element cityElement = new Element("city").setText(gameTO.getCity());
		System.out.println(gameTO.getCity());
		Element pointsToWinElement = new Element("pointsToWin").setText(
				String.valueOf(gameTO.getPointsToWin()));
		Element availablePointsElement = new Element("availablePoints").setText(
				String.valueOf(gameTO.getAvailablePoints()));
		Element currentPlayersElement = new Element("currentPlayers").setText(
				String.valueOf(gameTO.getCurrentPlayers()));
		Element maxPlayersElement = new Element("maxPlayers").setText(
				String.valueOf(gameTO.getMaxPlayers()));
		gameElement.addContent(gameIdElement);
		gameElement.addContent(startDateElement);
		gameElement.addContent(finishDateElement);
		gameElement.addContent(cityElement);
		gameElement.addContent(pointsToWinElement);
		gameElement.addContent(availablePointsElement);
		gameElement.addContent(currentPlayersElement);
		gameElement.addContent(maxPlayersElement);
		return gameElement;
	}
	
	public static Element toXML(AnswerQuestionResponseTO paqrTO) {
		Element paqrElement = new Element("answerQuestionResponse");
		Element serverResponseElement = toXML((GenericGameResponseTO)paqrTO);
		Element numberOfBonusOpenedElement = new Element(
				"numberOfBonusOpened").setText(String.valueOf(paqrTO.getNumberOfBonusesOpened()));
		paqrElement.addContent(serverResponseElement);
		paqrElement.addContent(numberOfBonusOpenedElement);
		return paqrElement;
	}
	
	private static Element toXML(GenericGameResponseTO ggrTO) {
		Element serverResponseElement = new Element("genericGameResponse");
		
		if (ggrTO.getInGamePlayerInfoTOs().size() > 0) { 
			Element playerLocationsElement = new Element("inGamePlayerInfos");
			for (InGamePlayerInfoTO inGamePlayerInfoTO:ggrTO.getInGamePlayerInfoTOs()) {
				Element playerLocationElement = new Element("inGamePlayerInfo");
				Element loginElement = 
					new Element("login").setText(inGamePlayerInfoTO.getLogin());
				Element pointsElement = 
					new Element("points").setText(String.valueOf(inGamePlayerInfoTO.getPoints()));
				Element itemsCaughtedElement = 
					new Element("numberOfItems").setText(String.valueOf(inGamePlayerInfoTO.getNumberOfItems()));
				Element latitudeElement = 
					new Element("latitude").setText(String.valueOf(inGamePlayerInfoTO.getLatitude()));
				Element longitudeElement = 
					new Element("longitude").setText(String.valueOf(inGamePlayerInfoTO.getLongitude()));
				Element imageIdElement = new Element("imageId").setText(
						String.valueOf(inGamePlayerInfoTO.getImageId()));
				playerLocationElement.addContent(loginElement);
				playerLocationElement.addContent(pointsElement);
				playerLocationElement.addContent(itemsCaughtedElement);
				playerLocationElement.addContent(latitudeElement);
				playerLocationElement.addContent(longitudeElement);
				playerLocationElement.addContent(imageIdElement);
				playerLocationsElement.addContent(playerLocationElement);
			}
			serverResponseElement.addContent(playerLocationsElement);
		}
		
		if (ggrTO.getVisibleItems().size() > 0) {
			Element visibleItemsElement = new Element("visibleItems");
			for (Item item:ggrTO.getVisibleItems()) {
				Element visibleItemElement = new Element("visibleItem");
				Element itemIdElement = 
					new Element("itemId").setText(String.valueOf(item.getItemId()));
				Element pointsElement = 
					new Element("points").setText(String.valueOf(item.getPoints()));
				Element latitudeElement = 
					new Element("latitude").setText(String.valueOf(item.getLatitude()));
				Element longitudeElement = 
					new Element("longitude").setText(String.valueOf(item.getLongitude()));
				Element typeElement = 
					new Element("type").setText(item.getType());
				visibleItemElement.addContent(itemIdElement);
				visibleItemElement.addContent(pointsElement);
				visibleItemElement.addContent(latitudeElement);
				visibleItemElement.addContent(longitudeElement);
				visibleItemElement.addContent(typeElement);
				
				visibleItemsElement.addContent(visibleItemElement);
			}
			serverResponseElement.addContent(visibleItemsElement);
		}
		
		if (ggrTO.getMyMessages().size() > 0) {
			Element messagesElement = new Element("messages");
			for (MessageTO messageTO:ggrTO.getMyMessages()) {
				Element messageElement = new Element("message");
				if (messageTO.getSenderLogin() != null) {
					Element senderLoginElement = 
						new Element("senderLogin").setText(messageTO.getSenderLogin());
					messageElement.addContent(senderLoginElement);
				}
				Element bodyElement = 
					new Element("body").setText(messageTO.getMessageBody());
				messageElement.addContent(bodyElement);
				Element typeElement = 
					new Element("type").setText(String.valueOf(messageTO.getType()));
				messageElement.addContent(typeElement);
				
				messagesElement.addContent(messageElement);
			}
			serverResponseElement.addContent(messagesElement);
		}
		
		if (ggrTO.isHasFinished()) {
			Element finishedElement = new Element("finished");
			serverResponseElement.addContent(finishedElement);
		}
		System.out.println("------- " + ggrTO.getMyMessages().size());
		return serverResponseElement;
	}
	
	public static Element toXML(GetItemResponseTO pgirTO) {
		Element pgiElement = new Element("getItemResponse");
		Element genericGameResponseElement = toXML((GenericGameResponseTO)pgirTO);
		pgiElement.addContent(genericGameResponseElement);
		if (pgirTO.isActuallyTaken()) {
			Element getsElement = new Element("actuallyGets");
			pgiElement.addContent(getsElement);
			
			Element playerPointsElement = new Element(
				"playerPoints").setText(String.valueOf(pgirTO.getPlayerPoints()));
			pgiElement.addContent(playerPointsElement);
	
			if (pgirTO.getQuestionTO() != null) {
				Element questionElement = new Element("question");
				
				Element qtElement = new Element("questionText").setText(pgirTO.getQuestionTO().getQuestion());
				questionElement.addContent(qtElement);
				
				if (pgirTO.getQuestionTO().getOption1() != null) {
					Element o1Element = new Element("option1").setText(pgirTO.getQuestionTO().getOption1());
					questionElement.addContent(o1Element);
				}
				if (pgirTO.getQuestionTO().getOption1() != null) {
					Element o2Element = new Element("option2").setText(pgirTO.getQuestionTO().getOption2());
					questionElement.addContent(o2Element);
				}
				if (pgirTO.getQuestionTO().getOption1() != null) {
					Element o3Element = new Element("option3").setText(pgirTO.getQuestionTO().getOption3());
					questionElement.addContent(o3Element);
				}
				Element raElement = new Element("rightAnswer").setText(
						String.valueOf(pgirTO.getQuestionTO().getRightAnswer()));
				questionElement.addContent(raElement);

				pgiElement.addContent(questionElement);
			}
		}
		return pgiElement;
	}
	
	public static Element toXMLCities(List<String> citiesList) {
		Element citiesElement = new Element("cities");
		for (String city:citiesList) {
			citiesElement.addContent(new Element("city").setText(city));
		}
		return citiesElement;
	}
	
	public static Element toXML(UpdateLocationResponseTO ulrTO) {
		Element ulElement = new Element("updateLocationReponse");
		ulElement.addContent(toXML((GenericGameResponseTO)ulrTO));
		return ulElement;
	}
	
	public static Element toXML(StartOrContinueGameResponseTO sgrTO) {
		Element startOrContinueElement = new Element("startOrContinueGameReponse");		
		Element playerPointsElement = new Element(
			"points").setText(String.valueOf(sgrTO.getPoints()));
		startOrContinueElement.addContent(playerPointsElement);
		Element numberOfItemsElement = new Element(
			"numberOfItems").setText(String.valueOf(sgrTO.getNumberOfItems()));
		startOrContinueElement.addContent(numberOfItemsElement);
		startOrContinueElement.addContent(toXML((GenericGameResponseTO)sgrTO));
		return startOrContinueElement;
	}
	
	public static Element toXML(ObserveGameResponseTO oGRTO) {
		Element observeGameElement = new Element("observeGameReponse");

		Element gameInfoElement = new Element("gameInfo");
		Element cityElement = new Element("city").setText(oGRTO.getCity());
		Element pointsToWinElement = new Element("pointsToWin").setText(String.valueOf(oGRTO.getPointsToWin()));
		Element maxPlayersElement = new Element("maxPlayers").setText(String.valueOf(oGRTO.getMaxPlayers()));
		gameInfoElement.addContent(cityElement);
		gameInfoElement.addContent(pointsToWinElement);
		gameInfoElement.addContent(maxPlayersElement);
		observeGameElement.addContent(gameInfoElement);
		if (oGRTO.getInGamePlayerInfoTOs().size() > 0) { 
			Element playerLocationsElement = new Element("inGamePlayerInfos");
			for (InGamePlayerInfoTO inGamePlayerInfoTO:oGRTO.getInGamePlayerInfoTOs()) {
				Element playerLocationElement = new Element("inGamePlayerInfo");
				Element loginElement = 
					new Element("login").setText(inGamePlayerInfoTO.getLogin());
				Element pointsElement = 
					new Element("points").setText(String.valueOf(inGamePlayerInfoTO.getPoints()));
				Element itemsCaughtedElement = 
					new Element("numberOfItems").setText(String.valueOf(inGamePlayerInfoTO.getNumberOfItems()));
				Element latitudeElement = 
					new Element("latitude").setText(String.valueOf(inGamePlayerInfoTO.getLatitude()));
				Element longitudeElement = 
					new Element("longitude").setText(String.valueOf(inGamePlayerInfoTO.getLongitude()));
				Element imageIdElement = new Element("imageId").setText(
						String.valueOf(inGamePlayerInfoTO.getImageId()));
				playerLocationElement.addContent(loginElement);
				playerLocationElement.addContent(pointsElement);
				playerLocationElement.addContent(itemsCaughtedElement);
				playerLocationElement.addContent(latitudeElement);
				playerLocationElement.addContent(longitudeElement);
				playerLocationElement.addContent(imageIdElement);
				playerLocationsElement.addContent(playerLocationElement);
			}
			observeGameElement.addContent(playerLocationsElement);
		}
		
		if (oGRTO.getItems().size() > 0) {
			Element itemsElement = new Element("items");
			for (ItemTO item : oGRTO.getItems()) {
				Element visibleItemElement = new Element("item");
				Element itemIdElement = 
					new Element("itemId").setText(String.valueOf(item.getId()));
				Element pointsElement = 
					new Element("points").setText(String.valueOf(item.getPoints()));
				Element latitudeElement = 
					new Element("latitude").setText(String.valueOf(item.getLatitude()));
				Element longitudeElement = 
					new Element("longitude").setText(String.valueOf(item.getLongitude()));
				Element typeElement = 
					new Element("type").setText(item.getType());
				visibleItemElement.addContent(itemIdElement);
				visibleItemElement.addContent(pointsElement);
				visibleItemElement.addContent(latitudeElement);
				visibleItemElement.addContent(longitudeElement);
				visibleItemElement.addContent(typeElement);
				
				itemsElement.addContent(visibleItemElement);
			}
			observeGameElement.addContent(itemsElement);
		}
		
		if (oGRTO.getMessages().size() > 0) {
			Element messagesElement = new Element("messages");
			for (MessageTO messageTO:oGRTO.getMessages()) {
				Element messageElement = new Element("message");
				if (messageTO.getSenderLogin() != null) {
					Element senderLoginElement = 
						new Element("senderLogin").setText(messageTO.getSenderLogin());
					messageElement.addContent(senderLoginElement);
				}
				if (messageTO.getReceiverLogin() != null) {
					Element receiverLoginElement = 
						new Element("receiverLogin").setText(messageTO.getReceiverLogin());
					messageElement.addContent(receiverLoginElement);
				}
				Element idElement = 
					new Element("id").setText(String.valueOf(messageTO.getId()));
				messageElement.addContent(idElement);
				Element bodyElement = 
					new Element("body").setText(messageTO.getMessageBody());
				messageElement.addContent(bodyElement);
				Element typeElement = 
					new Element("type").setText(String.valueOf(messageTO.getType()));
				messageElement.addContent(typeElement);
				
				messagesElement.addContent(messageElement);
			}
			observeGameElement.addContent(messagesElement);
		}
			
		return observeGameElement;
	}
}
